import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:aqua_plunge/http/Url.dart';
import 'package:aqua_plunge/http/app_manager.dart';
import 'package:aqua_plunge/util/header_util.dart';
import 'package:crypto/crypto.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_util_code/device_utils.dart';
import '../util/FoDeviceTool.dart';
import 'CxLogHeadersKey.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;

class LogPvManager{

  LogPvManager._();

  static const String _event = 'event';
  static const String _tm = 'tm';
  static const String _page = 'page';
  static const String _subPage = 'subPage';
  static const String _terPage = 'terPage';
  static const String _broadcasterId = 'broadcasterId';
  static const String _duration = 'duration';

  static void stat({
    String? page,
    String? subPage,
    String? terPage,
    String? broadcasterId,
  }) {
    var map = <String, dynamic>{};
    // ⚠️page传入下方的埋点事件page值
    if (page != null) {
      map[_page] = page;
    }
    if (subPage != null) {
      map[_subPage] = subPage;
    }
    if (terPage != null) {
      map[_terPage] = terPage;
    }
    if (broadcasterId != null) {
      map[_broadcasterId] = broadcasterId;
    }
    map[_duration] = 0;
    map[_event] = 'pv';
    map[_tm] = DateTime.now().millisecondsSinceEpoch;

    if (kDebugMode) {
      log('$map', name: 'LogPvMgr');
    }
    LogManger().putLog(LogType.globalBehavior, map);
  }
}

/// 打点类型
enum LogType {
  globalBehavior('event', 'global_behavior', 'event'),
  clickEvent("event", "click", "event");
  final String logType;
  final String subType;
  final String behavior;
  const LogType(this.logType, this.subType, this.behavior);
}

/// 打点中所有涉及到的页面KEY
class LogPages {
  final String launch_Page = 'launch';
  final String quicklogin_Page = 'quicklogin';
  final String applelogin_Page = 'applelogin';
  final String terms_Page = 'terms';
  final String privacy_Page = 'privacy';
  final String loginsuccess_Page = 'loginsuccess';
  final String purchase_Page = 'purchase';
  final String createorder_Page = 'createorder';
  final String editavatar_Page = 'editavatar';
  final String logout_Page = 'logout';
  final String deleteaccount_Page = 'deleteaccount';
  final String customer_Page = 'customer';
  final String report_Page = 'report';
  final String block_Page = 'block';

}

// 打点管理
class LogManger {
  static final LogManger _instance = LogManger._internal();
  factory LogManger() {
    return _instance;
  }
  LogManger._internal();

  static const String tag = "LogManger"; // 日志标签
  static const int limitSize = 20; // 打点任务最多缓存长度
  static int _serialId = 0;
  final List<Map<String, dynamic>> cacheList = [];
  bool _isWaitingForSend = false; // 是否需要延迟上报

  /// 上报日志
  void putLog(LogType logType, Map<String, dynamic>? event) async{
    if (logType.logType.isEmpty ||
        logType.subType.isEmpty ||
        logType.behavior.isEmpty ||
        event == null ||
        event.isEmpty) {
      return;
    }
    Map<String, dynamic> itemData = await _buildItemData(
        logType.logType, logType.subType, logType.behavior, event);
    cacheList.insert(0, itemData);
    sendDelayed();
  }

  /// 延时发送日志
  void sendDelayed() {
    if (_isWaitingForSend) {
      return;
    }
    _isWaitingForSend = true;
    Timer(const Duration(milliseconds: 2000), () {
      _isWaitingForSend = false;
      sendLog(false);
    });
  }

  /// 发日志打点
  void sendLog(bool forceUploadAll) {
    try {
      List<Map<String, dynamic>> sendList = [];
      if (cacheList.isEmpty) {
        return;
      } else if (cacheList.length >= limitSize && !forceUploadAll) {
        sendList.addAll(cacheList.sublist(0, limitSize));
        cacheList.removeRange(0, limitSize);
      } else {
        sendList.addAll(cacheList);
        cacheList.clear();
      }
      _doUpload(sendList);
    } catch (e) {
      if (kDebugMode) {
        print(e);
      }
    }
  }

  /// 立马发送日志
  void putLogRightNow(LogType logType, Map<String, dynamic>? event) async{
    if (logType.logType.isEmpty ||
        logType.subType.isEmpty ||
        logType.behavior.isEmpty ||
        event == null ||
        event.isEmpty) {
      return;
    }
    Map<String, dynamic> itemData = await _buildItemData(
        logType.logType, logType.subType, logType.behavior, event);
    List<Map<String, dynamic>> list = [];
    list.add(itemData);

    _doUpload(list);
  }

  String generateMd5(String input) {
    // Convert the string to bytes using UTF-8 encoding
    var bytes = utf8.encode(input);
    // Calculate MD5 hash
    var digest = md5.convert(bytes);
    // Return the hash as a string
    return digest.toString();
  }

  /// 执行上传
  Future<void> _doUpload(
      List<Map<String, dynamic>> sendList) async {
    
    try{
      final response = await http.post(
          Uri.parse(AppUrl.coverPosition),
        headers: await HeaderUtil().getHeader(),
        body: json.encode(sendList),
      );
      if(response.statusCode == 200 ){
        debugPrint('Event logged successfully: ${response.body}');
      }else{
        debugPrint('Failed to log event: ${response.body}');
      }
      
    }catch(e){
      debugPrint('Error logging event: $e');
    }
    
  }

  Future<Map<String, dynamic>> _buildItemData(String logType, String subType,
      String behavior, Map<String, dynamic>? event) async{
    String launcherId = generateMd5(
        '${DateTime.now().millisecondsSinceEpoch}${await DeviceUtils.getDeviceId()}');
    String platform = '';
    String model = '';
    if (Platform.isAndroid) {
      platform = 'Android';
      model = await DeviceUtils.getModel() ?? '';
    } else if (Platform.isIOS) {
      platform = 'iOS';
      model = await DeviceUtils.getModel() ?? '';
    }
    Map<String, dynamic> itemData = {};
    itemData[CxLogHeadersKey.cyxData] = [event];
    itemData[CxLogHeadersKey.cyxLogType] = 'event';
    itemData[CxLogHeadersKey.cyxSubtype] = 'global_behavior';
    itemData[CxLogHeadersKey.cyxBehavior] = 'event';
    itemData[CxLogHeadersKey.cyxUtmSource] = '';
    itemData[CxLogHeadersKey.cyxDeviceId] = await DeviceUtils.getDeviceId();
    itemData[CxLogHeadersKey.cyxUserId] = AppManager.getUserInfo().userId??'';
    itemData[CxLogHeadersKey.cyxPkg] = await FoDeviceTool.packName ?? '';
    itemData[CxLogHeadersKey.cyxVer] = await FoDeviceTool.appVersion ?? '';
    itemData[CxLogHeadersKey.cyxPlatform] = platform;
    itemData[CxLogHeadersKey.cyxPlatformver] = await DeviceUtils.getSystemVersion();
    itemData[CxLogHeadersKey.cyxModel] = model;
    itemData[CxLogHeadersKey.cyxLanId] = launcherId;
    itemData[CxLogHeadersKey.cyxSecId] = _serialId++;
    itemData[CxLogHeadersKey.cyxsysLan] = Get.locale?.languageCode ?? '';
    itemData[CxLogHeadersKey.cyxCountry] = Get.locale?.countryCode ?? '';
    itemData[CxLogHeadersKey.cyxisInbg] = false;
    itemData[CxLogHeadersKey.cyxisanchor] = false;
    itemData[CxLogHeadersKey.cyxclienttype] = 'common';
    itemData[CxLogHeadersKey.cyxbizver] = '';
    itemData[CxLogHeadersKey.cyxtm] = DateTime.now().millisecondsSinceEpoch;
    return itemData;
  }

}
